package com.bangdao.app.jetpacktest.jetpack.databinding.viewmodel;

import androidx.databinding.Bindable;
import androidx.databinding.Observable;
import androidx.databinding.PropertyChangeRegistry;
import androidx.lifecycle.ViewModel;

import com.bangdao.app.jetpacktest.BR;
import com.bangdao.app.jetpacktest.jetpack.databinding.bean.LoginModel;
import com.bangdao.app.jetpacktest.jetpack.databinding.bean.LoginModel1;

/**
 * @ProjectName: JetpackTest
 * @ClassName: TwoWayBindingViewModel
 * @Description: java类作用描述
 * @Author: luhui
 * @Email: hui.lu@bangdao-tech.com
 * @CreateDate: 2022/6/4 23:05
 * @UpdateUser: luhui
 * @UpdateDate: 2022/6/4 23:05
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 *
 * BaseObservable和Observable的区别?
 *
 * BaseObservable是实现了Observable的类, 帮我们实现了监听器的线程安全问题.
 * BaseObservable使用了PropertyChangeRegistry来执行OnPropertyChangedCallback
 * 所以我不推荐你直接实现Observable.
 *
 * 如果数据类的基类无法更改，Observable 接口可以使用 PropertyChangeRegistry 对象实现，以便有效地注册和通知监听器。
 *
 */
public class TwoWayBindingViewModel5 extends ViewModel implements Observable {
    private PropertyChangeRegistry callbacks = new PropertyChangeRegistry();
    private LoginModel loginModel;

    public TwoWayBindingViewModel5() {
        loginModel = new LoginModel();
        loginModel.setUserName("Jack");
    }

    @Bindable
    public String getUserName() {
        return loginModel.getUserName();
    }

    public void setUserName(String userName) {
        this.loginModel.setUserName(userName);
        notifyPropertyChanged(BR.userName);
        //或者，直接刷新所有，getter方法上不需要加@Bindable，因为不需要生成BR资源
//        notifyChange();
    }

    @Override
    public void addOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.add(callback);
    }

    @Override
    public void removeOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.remove(callback);
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    void notifyChange() {
        callbacks.notifyCallbacks(this, 0, null);
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes should be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    void notifyPropertyChanged(int fieldId) {
        callbacks.notifyCallbacks(this, fieldId, null);
    }
}
